/*
 * Created by SharpDevelop.
 * User: David
 * Date: 2007-01-14
 * Time: 22:39
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using NUnit.Framework;

using Labb4.Media.Sfx;
using Labb4.Pooman.Game;
using Labb4.Pooman.Cards;
using Labb4.Pooman.Players;
using Labb4.Rules;

namespace Labb4.Tests
{
	[TestFixture]
	public class TestStickRoundAi
	{
		[Test]
		public void TestPhase1()
		{
			FMODManager.Instance.Initialize();
			PoomanMain poo = new PoomanMain();
			Table.Instance.Subscribe(poo);
			PoomanRules.Instance.MainPoo = poo;
			
			while(PlayerManager.Instance.Count > 0)
			{
				PlayerManager.Instance.RemoveAt(0);
			}
			
			poo.ResetGame();
			
			AiStrategy aiStrategySuit = new AiStrategySuit();
			aiStrategySuit.Subscribe(poo);
			PoomanAiControl aiSuit = new PoomanAiControl(aiStrategySuit);
			Player aiSuitPlayer = new Player(aiSuit, Table.Instance.LeftArea);
			
			AiStrategy aiStrategyValue = new AiStrategyValue();
			aiStrategyValue.Subscribe(poo);
			PoomanAiControl aiValue = new PoomanAiControl(aiStrategyValue);
			Player aiValuePlayer = new Player(aiValue, Table.Instance.RightArea);
			
			aiSuitPlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Club, Card.Rank.Ace));
			aiValuePlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Heart, Card.Rank.Jack));
			
			/**
			 * There should be two players in the swarm, since the three players
			 * created in PoomanMain's constructor have all been removed from
			 * the PlayerManager
			 */
			PlayerSwarm swarm = new PlayerSwarm();
			swarm.Clear();
			PlayerManager.Instance.GetNextSwarm(aiSuitPlayer, swarm);
			Assert.AreEqual(2, swarm.Count);
			
			Stick stick = new Stick();
			
			/**
			 * This first call to GetWinner should return false, since only one
			 * of the two players have played yet
			 */
			bool foundWinner = stick.GetWinner(ref swarm);
			Assert.IsFalse(foundWinner);
			
			/**
			 * Now, the second call should return true, since both players in the
			 * swarm have played
			 */
			foundWinner = stick.GetWinner(ref swarm);
			Assert.IsTrue(foundWinner);
			
			/**
			 * And aiSuitPlayer should be the winner, with the ace being higher
			 * than the jack
			 */
			Player winner = stick.Winner;
			Assert.AreSame(winner, aiSuitPlayer);
		}
		
		[Test]
		public void TestPhase2()
		{
			FMODManager.Instance.Initialize();
			PoomanMain poo = new PoomanMain();
			Table.Instance.Subscribe(poo);
			PoomanRules.Instance.MainPoo = poo;
			poo.ResetGame();
			
			while(PlayerManager.Instance.Count > 0)
			{
				PlayerManager.Instance.RemoveAt(0);
			}
			
			Trump trump = new Trump();
			trump.SetTrump(Card.Suit.Heart);
			PoomanRules.Instance.CurrentTrump = trump;
			
			AiStrategy aiStrategySuit = new AiStrategySuit();
			aiStrategySuit.Subscribe(poo);
			PoomanAiControl aiSuit = new PoomanAiControl(aiStrategySuit);
			Player aiSuitPlayer = new Player(aiSuit, Table.Instance.LeftArea);
			
			AiStrategy aiStrategyValue = new AiStrategyValue();
			aiStrategyValue.Subscribe(poo);
			PoomanAiControl aiValue = new PoomanAiControl(aiStrategyValue);
			Player aiValuePlayer = new Player(aiValue, Table.Instance.RightArea);
			
			GameState state = new GameStatePhase2(poo);
			poo.SetSubjectsState(state);
			
			//here we set up the hands (suit 5 cards, value 1)
			//suit will go first, and play cards that value will have to pick up
			//value picks up 3 times, which is maximum allowed, then it's value's
			//turn to play. suit turns the cards, and we have our winner.
			//after this, suit should have 1 card (king of clubs), and value should have 3
			aiSuitPlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Diamond, Card.Rank.Ace));
			aiSuitPlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Club, Card.Rank.Seven));
			aiSuitPlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Club, Card.Rank.Nine));
			aiSuitPlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Club, Card.Rank.Jack));
			Card king = new Card(Card.Suit.Club, Card.Rank.King);
			aiSuitPlayer.CurrentHand.Cards.Add(king);
			aiValuePlayer.CurrentHand.Cards.Add(new Card(Card.Suit.Diamond, Card.Rank.Five));
			
			PlayerSwarm swarm = new PlayerSwarm();
			swarm.Clear();
			PlayerManager.Instance.GetNextSwarm(aiSuitPlayer, swarm);
			
			Stick stick = new Stick();
			
			/**
			 * Suit plays seven of clubs (now has 4 cards), and there is 1 play on the table,
			 * two needed for winner to be found
			 */
			bool foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(1, PoomanRules.Instance.CurrentRound.Plays);
			Assert.AreEqual(7, PoomanRules.Instance.CurrentRound.GetHighestCardInPlay(trump).ValueOfCard);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Value can't top it, and has to pick it up, now has 2 cards, there's now
			 * 0 plays on the table
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(0, PoomanRules.Instance.CurrentRound.Plays);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Suit plays nine of clubs (now has 3 cards), and there is 1 play on the table,
			 * two needed for winner to be found
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(1, PoomanRules.Instance.CurrentRound.Plays);
			Assert.AreEqual(9, PoomanRules.Instance.CurrentRound.GetHighestCardInPlay(trump).ValueOfCard);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Value can't top it, and has to pick it up, now has 3 cards, and again there's
			 * now 0 plays on the table
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(0, PoomanRules.Instance.CurrentRound.Plays);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Suit plays jack of clubs (now has 2 cards), and there is 1 play on the table,
			 * two needed for winner to be found
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(1, PoomanRules.Instance.CurrentRound.Plays);
			Assert.AreEqual(11, PoomanRules.Instance.CurrentRound.GetHighestCardInPlay(trump).ValueOfCard);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Value can't top it, and has to pick it up, now has 4 cards, and again there's
			 * now 0 plays on the table
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(0, PoomanRules.Instance.CurrentRound.Plays);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Since value has picked up 3 times, it's now values turn to act, and plays its
			 * lowest card, the 5 of diamonds, now has 3 cards, and there's 1 play on the table
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.AreEqual(1, PoomanRules.Instance.CurrentRound.Plays);
			Assert.AreEqual(5, PoomanRules.Instance.CurrentRound.GetHighestCardInPlay(trump).ValueOfCard);
			Assert.IsFalse(foundLastPlayer);
			
			/**
			 * Suit plays the ace of diamonds (now has 1 card), making it 2 plays on the table,
			 * meaning we have a last player
			 */
			foundLastPlayer = stick.GetLastPlayer(ref swarm);
			Assert.IsTrue(foundLastPlayer);
			
			Player winner = stick.Winner;
			
			/**
			 * The last player should be suit, who should have 1 card, the king of clubs
			 * Value on the other "hand", should have 3 cards
			 */
			Assert.AreSame(winner, aiSuitPlayer);
			Assert.AreEqual(1, aiSuitPlayer.CurrentHand.Cards.Count);
			Assert.AreSame(king, aiSuitPlayer.CurrentHand.Cards[0]);
			Assert.AreEqual(3, aiValuePlayer.CurrentHand.Cards.Count);
		}
	}
}
